#!/usr/bin/perl

$DEBUG = 0;
if($DEBUG) {
	$maedir = "./";
	$procdir = "./";
	$repodir = "./";
} else {
	$maedir = $ENV{"MAEDIR"};
	$procdir = $ENV{"PROCDIR"};
	$repodir = $ENV{"REPODIR"};
	$grupo = $ENV{"GRUPO"};
}

#output
#repodir.<id del combo>.inv
#repodir.<nombre ingresado>.inv
#repodir.ranking.nnn
#repodir.<id del combo>.fck

if ( !$maedir || !$procdir || !$repodir || !$grupo)   {
        print "Las variables de ambiente no están inicializadas.\n";
        exit 1;
}


#imprime el menu de ayuda
sub ayuda {
        print "\nImprimir_B\t\t\t\tComandos\n";
        print "Nombre:\n";
        print "\tImprimir_B - imprime reportes que reportean por salida estándar\n";
        print "Sinopsis:\n";
        print "\tImprimir_B [-a | COMANDO] [-w]\n";
        
        print "Descripción:\n";
        print "\t-a, --ayuda\n";
        print "\t\tImprime este menú de ayuda.\n";

	print "\tCOMANDO:\n";

        print "\t\t-i, --invitados\n";
        print "\t\t\tGenera el listado de invitados para un evento dado.\n";

        print "\t\t-d, --disponibilidad\n";
        print "\t\t\tGenera un listado con las disponibilidades.\n";

        print "\t\t-r, --ranking\n";
        print "\t\t\tGenera un ranking con los principales solicitantes.\n" ;

        print "\t\t-t, --ticket\n";
        print "\t\t\tGenera el listado de tickets a imprimir.\n";

        print "\t-w, --grabar\n";
        print "\t\tAdemás de la salida por pantalla escribe el reporte en un archivo.\n";

	exit 1;
}

sub solicitarEntrada {
	my($mensaje) = @_;
	print $mensaje;
	my($input) = <STDIN>;
	chomp($input);
	print "\n";
	# devuelvo los parametros separados por espacios
	return(split(/\s+/, $input)); 
}

%archivos = ();
$archivos{"obras"} = "${grupo}/${maedir}/obras.mae";
$archivos{"salas"} = "${grupo}/${maedir}/salas.mae";
$archivos{"reservasOk"} = "${grupo}/${procdir}/reservas.ok";
$archivos{"reservasNok"} = "${grupo}/${procdir}/reservas.nok";
$archivos{"combos"} = "${grupo}/${procdir}/combos.dis";

#en estas variables vamos a guardar el separador de campo para cada salida
$sci = '';
$scd = '';
$scr = ',';
$sct = ',';
@parametros = @ARGV;
$cantParametros = @parametros;

if ($cantParametros < 1 || $cantParametros > 2) {
	print "Cantidad de parámetros incorrecta.\n";
	&ayuda();
}

%operaciones = ();	
$operaciones{"grabar"} = 0;

if($cantParametros == 2) {
	if($parametros[1] eq "-w" || $parametros[1] eq "--grabar") {
		$operaciones{"grabar"} = 1;
	} else {
		print "Segundo parámetro incorrecto\n";
		&ayuda();
	}
}

$param = $parametros[0];
if($param eq "-a" || $param eq "--ayuda") {
	&ayuda();		
} else {
	#expresiones regulares para los distintos campos.
	$fFecha = '[0-3][0-9]\/[0-1][0-9]\/[12][0-9][0-9][0-9]';
	$fHora = '[0-2][0-9]:[0-5][0-9]';
	$fIdObra = '[0-9]*[13579]';
	$fIdSala = '[0-9]*[02468]';
	$fIdCombo = '[^;]+';
	
	if($param eq "-i" || $param eq "--invitados") {
		#---------------------------------------------------------------------------------------------------------------------- invitados
		#imprimir por pantalla los eventos candidatos
		%eventos = ();
		open(COMBOS_DIS, $archivos{"combos"});	 
	
		while ($linea = <COMBOS_DIS>) {
			if($linea =~ /^($fIdCombo);($fIdObra);($fFecha);($fHora);($fIdSala);([0-9]*);([0-9]*);/) {
				#$1 id combo
				#$2 id obra
				#$3 fecha funcion dd/mm/yyyy
				#$4 hora funcion hh:mm
				#$5 id de la sala
				#$6 butacas habilitadas
				#$7 butacas disponibles
				#$8 requisitos especiales
				
				$idCombo = $1;
				$idObra = $2;
				$fechaFuncion = $3;
				$horaFuncion  = $4;		
				$idSala = $5;
				$butacasHabilitadas = $6;
				$butacasDisponibles = $7;
				if ( $butacasHabilitadas > $butacasDisponibles) {
					open(RESERVAS_OK, $archivos{"reservasOk"});
					#busco que ese evento tenga alguna referencia interna
					while ($lineaReservasOk = <RESERVAS_OK>) {
						if ($lineaReservasOk =~ /^($fIdObra);([^;]+);($fFecha);($fHora);($fIdSala);([^;]+);([0-9]*);($idCombo);([^;]*);([0-9]+);([^;]+);($fFecha);([^;]+)$/) {
							#$1 idObra
							#$2 nombreObra
							#$3 fechaFuncion
							#$4 horaFuncion
							#$5 idSala
							#$6 nombreSala
							#$7 butacasConfirmadas
							#$8 idCombo
							#$9 referencia
							#$10 butacasSolicitadas
							#$11 correoSolicitante
							#$12 fechaGrabacion
							#$13 usuario
							$butacasConfirmadas = $7;
							$referencia = $9;
							if($referencia && $butacasConfirmadas > 0 && -f "$grupo/$repodir/$referencia\.inv") {
								@eventos{$idCombo} = [ $idCombo, $idObra, $fechaFuncion, $horaFuncion, $idSala ];
							}
						}
					}
					close(RESERVAS_OK);
				}
			}
		}
		close(COMBO_DIS);
		@clavesEventos = keys(%eventos);
		if ($#clavesEventos) {
			print "No hay eventos candidatos con lista de invitados.\n";
			exit 2;
		}	
		print "A continuación se muestra un listado con los eventos candidatos.\n";
		print "Id evento\tObra\tFecha\t\tHora\tSala\n";
		foreach $key (@clavesEventos) {
			print "$eventos{$key}[0]\t$eventos{$key}[1]\t$eventos{$key}[2]\t$eventos{$key}[3]\t$eventos{$key}[4]\n";
		}

		#y que seleccione uno valido
		@input = &solicitarEntrada("Ingrese el id del evento  para el cual desee ver sus invitados.\n");
		$idComboElegido = $input[0];
			
		if ($eventos{$idComboElegido}[0] == $idComboElegido) {
		
			$idObraElegida = $eventos{$idComboElegido}[1];
			$fechaFuncionElegida = $eventos{$idComboElegido}[2];
			$horaFuncionElegida = $eventos{$idComboElegido}[3];
			$idSalaElegida = $eventos{$idComboElegido}[4];	

			#busco el nombre de la obra
			open(OBRAS, $archivos{"obras"});
			while($linea = <OBRAS>) {
				if($linea =~ /^($idObraElegida);([^;]+);([^;]+);([^;]+)$/) {
					#$1 idObra
					#$2 nombreObra
					#$3 correoProduccionGeneral
					#$4 correoProduccionEjecutiva
					
					$nombreObra = $2;
					push(@eventos{$idComboElegido}, $nombreObra);
				}
			}
			close(OBRAS);

			#busco el nombre de la sala
			open(SALAS, $archivos{"salas"});
			while($linea = <SALAS>) {
				if($linea =~ /^($idSalaElegida);([^;]+);([0-9]+);([^;]+);([^;]+);([^;]+)$/) {
					#$1 idSala
					#$2 nombreSala
					#$3 capacidadSala
					#$4 direccion
					#$5 telefono
					#$6 correoTeatro 
					
					$nombreSala = $2;
					push(@eventos{$idComboElegido}, $nombreSala);
				}
			}
			close(SALAS);

			#busco las referencias internas de los que solicitaron entradas.
			open(RESERVASOK, $archivos{"reservasOk"});
			
			%invitados = ();
			%sinInvitados = ();
			while ($lineaReservas = <RESERVASOK>) {
				if ($lineaReservas =~ /^($fIdObra);([^;]+);($fFecha);($fHora);($fIdSala);([^;]+);([0-9]*);($idComboElegido);([^;]*);([0-9]+);([^;]+);($fFecha);([^;]+)$/) {
					#$1 idObra
					#$2 nombreObra
					#$3 fechaFuncion dd/mm/yyyy
					#$4 horaFuncion hh/mm
					#$5 idSala
					#$6 nombreSala
					#$7 butacasConfirmadas
					#$8 idcombo
					#$9 referenciaInterna
					#$10 butacasSolicitadas
					#$11 correoSolicitante
					#$12 fechaGrabacion
					#$13 usuarioGrabacion
			
					$butacasConfirmadas = $7;
					$referenciaInterna = $9;
					$butacasSolicitadas = $10;
					$correoSolicitante = $11;
			
					#si no es vacia la referencia interna y hay confirmados busco por el archivo	
					if($referenciaInterna && $butacasConfirmadas > 0) {
						$tieneInvitados = 0;
						if( -f "$grupo/${repodir}/${referenciaInterna}\.inv") {
							if ( open(INVITADOS, "$grupo/$repodir/$referenciaInterna\.inv")) {
								$i = 0;
								while($lineaInvitados = <INVITADOS>) {
									if( $lineaInvitados =~ /^([^;]*);([^;]*);([0-9]*)/) {
										#$1 nombreInvitado
										#$2 empresa
										#$3 cantidadAcompanantes
										$tieneInvitados = 1;
										$key = $referenciaInterna.'00'.$i;
										$nombreInvitado = $1;
										$cantInvitados = $3;
										if (! $cantInvitados) {
											$cantInvitados = 0;
										}
										@invitados{$key} = [ $referenciaInterna, $nombreInvitado, $cantInvitados, $butacasConfirmadas ];
										$i++;
									}
								}
								close(INVITADOS);
							}
						} 
					
						if (! $tieneInvitados) {
							$sinInvitados{$referenciaInterna} = "Sin listado de invitados";		
						}

					}
				}
			}	
			close(RESERVASOK);

			$nombreObraElegida = $eventos{$idComboElegido}[5];
			$nombreSalaElegida = $eventos{$idComboElegido}[6];
			#ordeno por referencia interna para que queden juntos los invitados de cada referencia.
			@invitadosOrdenados = sort { $invitados{$a}[0] <=> $invitados{$b}[0] } keys(%invitados);
		
			#imprimo el reporte por consola
			$refAnterior = '';
			$claveAnterior = '';
			$butacasConfirmadasAnterior = 0;
			$invitadosTotales = 0;
			$invitadosPorReferencia = 0;

			#si selecciono la opcion de grabar escribo en el archivo
			if ($operaciones{"grabar"}) {
				open (REPORTE_INVITADOS, ">$grupo/$repodir/$idComboElegido.inv");
			}
			$msg = "Evento:$idComboElegido Obra:$idObraElegida-$nombreObraElegida Fecha y hora:$fechaFuncionElegida-$salaFuncionElegida Hs. Sala:$idSalaElegida-$nombreSalaElegida\n";
			print $msg;
			if ($operaciones{"grabar"}) {
				print REPORTE_INVITADOS $msg;
			}

			$refAnterior = '';
			$claveAnterior = '';
			$butacasConfirmadasAnterior = 0;
			$invitadosTotales = 0;
			$invitadosPorReferencia = 0;
			foreach $clave (@invitadosOrdenados) {
				if ($refAnterior ne $invitados{$clave}[0]) { 
					#proceso una nueva ref
					if ($butacasConfirmadasAnterior) {
						$msg = "\tReservas confirmadas: $invitados{$claveAnterior}[3] - $invitadosPorReferencia\n";
						print $msg;
						if ($operaciones{"grabar"}) {
							print REPORTE_INVITADOS $msg;
						}

						$invitadosPorReferencia = 0;
						$msg = "Ref interna: $invitados{$clave}[0]\n";
						print $msg;
						if ($operaciones{"grabar"}) {
							print REPORTE_INVITADOS $msg;
						}
					} 
					$invitadosPorReferencia += $invitados{$clave}[2] + 1;
					$invitadosTotales += $invitados{$clave}[2] + 1;
					$msg =  "\t$invitados{$clave}[1],$invitados{$clave}[2],$invitadosPorReferencia\n";
					print $msg;
					if ($operaciones{"grabar"}) {
						print REPORTE_INVITADOS $msg;
					}
					$butacasConfirmadasAnterior = $invitados{$clave}[3];
					$claveAnterior = $clave;
					$refAnterior = $invitados{$clave}[0];
				}
			}
			$msg = "\tReservas confirmadas: $invitados{$claveAnterior}[3] - $invitadosPorReferencia\n";
			print $msg;
			if ($operaciones{"grabar"}) {
				print REPORTE_INVITADOS $msg;
			}
		
			foreach $clave (keys(%sinInvitados)) {
				$msg = "Ref interna: $clave\n\t$sinInvitados{$clave}\n";
				print $msg;
				if ($operaciones{"grabar"}) {
					print REPORTE_INVITADOS $msg;
				}
			}
		
				
		} else {
			print "Error: Id de evento no existente.\n";
			exit 3;
		}
	} elsif ($param eq "-d" || $param eq "--disponibilidad") {
		#---------------------------------------------------------------------------------------------------------------------- disponibilidad
		$operaciones{"sala"} = 0; 
		$operaciones{"obra"} = 0;
		$operaciones{"rango"} = 0; 
		
		#solicitar que ingrese el id rango de obras o salas.
	  	open(COMBOS_DIS, $archivos{"combos"});
                $i = 0;

                @input = &solicitarEntrada("Ingrese el id de obra o de sala a buscar.\n");
		$idMin = $input[0];
		$idMax = $input[1];
	
		if ($idMin =~ /$fIdSala$/) {
			#al ser un numero par esta buscando una sala.
			$operaciones{"sala"} = 1;
			if ($idMax =~ /[0-9]+$/) {
				$operaciones{"rango"} = 1;
			}
		} elsif ($idMin =~ /$fIdObra$/) {
			#al ser un numero impar se busca una obra.
			$operaciones{"obra"} = 1;
			if ($idMax =~ /[0-9]+$/) {
				$operaciones{"rango"} = 1;
			}
		}
		%reporte = ();
                while ($linea = <COMBOS_DIS>) {
		
                        if($linea =~ /^($fIdCombo);($fIdObra);($fFecha);($fHora);($fIdSala);([0-9]+);([0-9]+);/) {
                                #$1 id combo
                                #$2 id obra
                                #$3 fecha funcion dd/mm/yyyy
                                #$4 hora funcion hh:mm
                                #$5 id de la sala
                                #$6 butacas habilitadas
                                #$7 butacas disponibles
                                #$8 requisitos especiales

                                $idCombo = $1;
                                $idObra = $2;
                                $fechaFuncion = $3;
				$horaFuncion = $4;
				$idSala = $5;
				$butacasHabilitadas = $6;
				$butacasDisponibles = $7;
				
				$valid = 0;
				if ($operaciones{"sala"} ) {
					$idAVerificar = $idSala;
				} elsif ($operaciones{"obra"}) {
					$idAVerificar = $idObra;
				} else {
					$idAVerificar = -1;
				}
				if($operaciones{"rango"}) {
					if ($idAVerificar >= $idMin && $idAVerificar <= $idMax) {
						$valid = 1;
					}
				} else {
					if ($idAVerificar == $idMin) {
						$valid = 1;
					}
				} 

				if ($valid) {
					@reporte{$idCombo} = [ $idCombo, $idObra, $fechaFuncion, $horaFuncion, $idSala, $butacasHabilitadas, $butacasDisponibles ]; 
				}
                        }
                }
                close(COMBOS_DIS);
		if ( $operaciones{"grabar"}) {
			@input = &solicitarEntrada("Por favor, ingrese un nombre de archivo para guardar el reporte.\n");
			$nombreIngresado = $input[0];
			while ($nombreIngresado eq 'combos' || $nombreIngresado eq '') {
				@input = &solicitarEntrada("Error: nombre inválido.\nPor favor elija otro nombre.\n");
				$nombreIngresado = $input[0];
			}

			open(REPORTE_DISPONIBILIDAD, ">$grupo/$repodir/$nombreIngresado.dis");
		}
		$msg = "idCombo\t\tidObra\tfechaFuncion\thoraFuncion\tidSala\tbutacasHabilitadas\tbutacasDisponibles\n";  
		print $msg;

		if ($operaciones{"grabar"}) {
			print REPORTE_DISPONIBILIDAD $msg 
		}
		foreach $id (keys(%reporte)) {
			$msg =  "$reporte{$id}[0]\t$reporte{$id}[1]\t$reporte{$id}[2]\t$reporte{$id}[3]\t\t$reporte{$id}[4]\t$reporte{$id}[5]\t\t\t$reporte{$id}[6]\n";

			print $msg;

			if ($operaciones{"grabar"}) {
				print REPORTE_DISPONIBILIDAD $msg;
			}
		}
		if ($operaciones{"grabar"}) {
			close(REPORTE_DISPONIBILIDAD);
		} 

	} elsif($param eq "-r" || $param eq "--ranking") {
		#---------------------------------------------------------------------------------------------------------------------- ranking
		%solicitantes = ();
		open(RESERVAS_OK, $archivos{"reservasOk"});
		
		while ($lineaReservas = <RESERVAS_OK>) {
			
                	if ($lineaReservas =~ /($fIdObra);([^;]+);($fFecha);($fHora);($fIdSala);([^;]+);([0-9]*);($fIdCombo);([^;]*);([0-9]+);([^;]+);($fFecha);([^;]+)$/) {
				#$1 idObra
				#$2 nombreObra
				#$3 fechaFuncion dd/mm/yyyy
				#$4 horaFuncion hh/mm
				#$5 idSala
				#$6 nombreSala
				#$7 butacasConfirmadas
				#$8 idcombo
				#$9 referenciaInterna
				#$10 butacasSolicitadas
				#$11 correoSolicitante
				#$12 fechaGrabacion
				#$13 usuarioGrabacion
			
				$referenciaInterna = $9;
				$butacasSolicitadas = $10;
				$correoSolicitante = $11;
								
				if(! -z $referenciaInterna) {
					if(exists($solicitantes{$referenciaInterna})) {
						$butacasSolicitadas += $solicitantes{$referenciaInterna}[0];					
					}
					@solicitantes{$referenciaInterna} = [$butacasSolicitadas, $correoSolicitante];
				}
			}
		}	
		close(RESERVAS_OK);
		
		#ordenar el hash ver si sirve
		@mayoresSolicitantes = sort { $solicitantes{$b}[0] <=> $solicitantes{$a}[0] } keys(%solicitantes);
		@claves = keys(%solicitantes);
		
		if($operaciones{"grabar"}) {
			$dirValido = 1;
			$cantReportes = 1;
			if( opendir(REPODIR, "$grupo/$repodir/")) {
				while ($archivoRepo = readdir(REPODIR)) {
					if ( (-f "$grupo/$repodir/$archivoRepo") && ($archivoRepo =~ /[0-9]{3,3}$/) ) {
						$cantReportes++;
					}
				}
				closedir(REPODIR);
			} else {
				$dirValido = 0;
				print "No se ha podido abrir el directorio $grupo/$repodir, no se grabará el archivo.\n";
			}
			
			#pasar $cantReportes a un numero de 3 cifras
			if( 0 < $cantReportes && $cantReportes <= 9) {
				$cantReportes = "00$cantReportes";
			} elsif ( 10 <= $cantReportes && $cantReportes <= 99) {
				$cantReportes = "0$cantReportes";
			}
		}
		$grabar = $operaciones{"grabar"} && $dirValido;
		if( $grabar) {
			open(REPORTE_RANKING, ">$grupo/${repodir}/ranking\.$cantReportes");
		}
		#imprimo los 10 que mas solicitaron
		$msg = "Ranking: Correo${scr}butacas solicitadas\n";
		print $msg;
		if( $grabar) {
			print REPORTE_RANKING $msg; 
		}
		for ($i=0; $i<10 && $i<$#claves; $i++) {
			$clave = $mayoresSolicitantes[$i];
			$ranking = $i + 1;
			$msg = "$ranking: $solicitantes{$clave}[1]${scr}$solicitantes{$clave}[0]\n"; 
			print $msg;
			if( $grabar) {
				print REPORTE_RANKING $msg;
			}
		}	
		if ($grabar) {
			close(REPORTE_RANKING);
		}
	} elsif($param eq "-t" || $param eq "--ticket") {
		#---------------------------------------------------------------------------------------------------------------------- tickets
	
		#solicitar un id de combo hasta que ingrese uno correcto.
		$idNoCorrecto = 1;
		%tickets = ();
		while ($idNoCorrecto) {
			@input = &solicitarEntrada("Por favor, ingrese el id del combo que desea imprimir sus tickets.\n");
			$idCombo = $input[0];
			$j = 0;
			open(RESERVAS_OK, $archivos{"reservasOk"});
	       	        while ($lineaReservas = <RESERVAS_OK>) {

                	        if ($lineaReservas =~ /($fIdObra);([^;]+);($fFecha);($fHora);($fIdSala);([^;]+);([0-9]*);($idCombo);([^;]*);([0-9]+);([^;]+);($fFecha);([^;]+)$/) {
                        	        #$1 idObra
                        	        #$2 nombreObra
                        	        #$3 fechaFuncion dd/mm/yyyy
                        	        #$4 horaFuncion hh/mm
                        	        #$5 idSala
                        	        #$6 nombreSala
                        	        #$7 butacasConfirmadas
                        	        #$8 idcombo
                        	        #$9 referenciaInterna
                        	        #$10 butacasSolicitadas
                        	        #$11 correoSolicitante
                        	        #$12 fechaGrabacion
                                	#$13 usuarioGrabacion

                              	 	$butacasConfirmadas = $7;
					$nombreObra = $2;
					$fechaFuncion = $3;
					$horaFuncion = $4;
					$nombreSala = $6;
                              		$referenciaInterna = $9;
                              	 	$correoSolicitante = $11;

					@tipoTickets = ();
					while($butacasConfirmadas > 1) {
						push(@tipoTickets, "VALE POR 2 ENTRADAS");
						$butacasConfirmadas -= 2;
					}
					
					if ($butacasConfirmadas == 1) {
						$butacasConfirmadas--;	
						push(@tipoTickets, "VALE POR 1 ENTRADA");
					}
					foreach $tipoTicket (@tipoTickets) {
						@tickets{$j} = [ $tipoTicket, $nombreObra, $fechaFuncion, $horaFuncion, $nombreSala, $referenciaInterna, $correoSolicitante];	
						$j++;
						$idNoCorrecto = 0;
					}
                        	}	
                	}
			if($idNoCorrecto) {
				print "Error: id no encontrado.\n";
			}	
                	close(RESERVAS_OK);
		}

		if ( $operaciones{"grabar"}) {
			open(REPORTE_TICKETS, ">$grupo/$repodir/$idCombo.tck");
		}
		$msg = "Tipo comprobante${sct}Nombre obra${sct}Fecha función${sct}Hora función${sct}Nombre sala${sct}Referencia interna${sct}Correo\n";
		print $msg;
		if ($operaciones{grabar}) {
			print REPORTE_TICKETS $msg;
		}
		foreach $id (keys(%tickets)) {
			$msg = "$tickets{$id}[0]$sct$tickets{$id}[1]$sct$tickets{$id}[2]$sct$tickets{$id}[3]$sct$tickets{$id}[4]$sct$tickets{$id}[5]$sct$tickets{$id}[6]\n";
			print $msg;
			if ($operaciones{grabar}) {
				print REPORTE_TICKETS $msg;
			}
		}
		if ( $operaciones{"grabar"}) {
			close(REPORTE_TICKETS);
		}

	} else {
		print "Parámetro incorrecto.\n";
		&ayuda();
	}
}

exit 0;
